package com.lwl.concurrency.collection;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author liwenlong - 2018/4/1 21:34
 */
public class ThreadLocalDemoGc {

    static volatile ThreadLocal<SimpleDateFormat> local = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println(this.toString() + " is gc!!!");
        }
    };

    static volatile CountDownLatch latch = new CountDownLatch(10000);

    public static class ParseDate implements Runnable {
        int i = 0;

        public ParseDate(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            try {
                SimpleDateFormat format = local.get();
                if (format == null) {
                    local.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {
                        private static final long serialVersionUID = -3520260191707059674L;
                        @Override
                        protected void finalize() throws Throwable {
                            System.out.println(this.toString() + " is gc");
                        }
                    });
                    System.out.println(Thread.currentThread().getName() + " create SimpleDateFormat");
                }
                Date date = local.get().parse("2018-04-01 20:53:" + (i % 60));

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10000; i++) {
            executorService.execute(new ParseDate(i));
        }
        latch.await();
        System.out.println("mission complete!!");
        local = null;
        System.gc();
        System.out.println("first GC complete!!");
        Thread.sleep(1000);

        local = new ThreadLocal<>();
        latch = new CountDownLatch(10000);
        for (int i = 0; i < 10000; i++) {
            executorService.execute(new ParseDate(i));
        }
        latch.await();
        Thread.sleep(1000);
        System.gc();
        System.out.println("last GC complete!!");
        //executorService.shutdown();
    }


}
